package com.ray.controller.base;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.ray.flow.FlowService;
import com.ray.log.WebLog;
import com.ray.model.*;
import com.ray.util.Ret;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

/**
 * 流程设计及处理类
 */
@RestController
@RequestMapping("/flow")
public class FlowController extends BaseController{


    @Autowired
    private FlowService flowService;

    /**
     * @note 解析并保存流程设计
     * @time 2024年03月26日 11:19:39
     * @author Ray
     */
    @RequestMapping("save")
    @WebLog(description = "")
    @Transactional("baseTransactionManager")
    public Ret save(@RequestBody JSONObject flowDesign) {
        //更新业务流程json
        FlowDesign design = FlowDesign.dao.findFirst("select * from flow_design where no = ?", flowDesign.getString("no"));
        design.setJson(flowDesign.getJSONObject("json").toJSONString());
        design.setUpdateTime(new Date());
        design.update();
        //删除之前定义的审批节点
        Db.use(base).update("delete from flow_design_node where flow_design_no = ?", flowDesign.getString("no"));
        //解析流程设计
        JSONObject root = flowDesign.getJSONObject("json").getJSONObject("process");
        //发起人节点
        FlowDesignNode rootFD = new FlowDesignNode();
        rootFD.setRegion(getSessionUserRegion())
                .setFlowDesignNo(flowDesign.getString("no"))
                .setNo("root")
                .setName(root.getString("name"))
                .setType("ROOT")
                .setCreateUserId(getSessionUserId())
                .setCreateUserName(getSessionUsername())
                .save();
        //递归新增所有子节点
        recursiveNode(flowDesign.getString("no"), "root", root.getJSONObject("children"));
        return Ret.ok("msg", "成功");
    }

    /**
     * 递归新增子节点
     *
     * @param flowDesignNo 流程编号
     * @param parent_no    父节点
     * @param children     子节点
     */
    public void recursiveNode(String flowDesignNo, String parent_no, JSONObject children) {
        FlowDesignNode fd = new FlowDesignNode();
        fd.setRegion(getSessionUserRegion())
                .setFlowDesignNo(flowDesignNo)
                .setNo(children.getString("id"))
                .setName(children.getString("name"))
                .setType(children.getString("type"))
                .setCreateUserId(getSessionUserId())
                .setCreateUserName(getSessionUsername())
                .setParentNo(parent_no);
        JSONObject props = children.getJSONObject("props");
        //根据type判断节点类型(ROOT(发起人，根节点)、APPROVAL(审批)、CC(抄送)、CONDITIONS(条件组))
        if (children.getString("type").equals("APPROVAL")) {
            //审批处理的类型(ASSIGN_USER 指定人员、SELF 发起人自己、FORM_USER指定表单联系人)
            //驳回设置
            fd.setRefuseType(props.getJSONObject("refuse").getString("type"));
            //审批人类型设置
            fd.setAssignedType(props.getString("assignedType"));
            //指定人员
            if (props.getString("assignedType").equals("ASSIGN_USER")) {
                fd.setMode(props.getString("mode"));
                String userids = "";
                String usernames = "";
                for (int i = 0; i < props.getJSONArray("assignedUser").size(); i++) {
                    userids += props.getJSONArray("assignedUser").getJSONObject(i).getString("id") + ",";
                    usernames += props.getJSONArray("assignedUser").getJSONObject(i).getString("name") + ",";
                }
                fd.setUserid(userids.substring(0, userids.length() - 1));
                fd.setUsername(usernames.substring(0, usernames.length() - 1));
            }
            //表单内人员字段
            else if (props.getString("assignedType").equals("FORM_USER")) {
                fd.setFormUser(props.getString("formUser"));
            }
        } else if (children.getString("type").equals("CC")) {
            //抄送的处理类型(ASSIGN_USER 指定人员、SELF 发起人自己)
            //指定人员
            String userids = "";
            String usernames = "";
            for (int i = 0; i < props.getJSONArray("assignedUser").size(); i++) {
                userids += props.getJSONArray("assignedUser").getJSONObject(i).getString("id") + ",";
                usernames += props.getJSONArray("assignedUser").getJSONObject(i).getString("name") + ",";
            }
            fd.setUserid(userids.substring(0, userids.length() - 1));
            fd.setUsername(usernames.substring(0, usernames.length() - 1));
        }
        //是否是多人审批模式
        if (props.getJSONArray("assignedUser").size() > 1) {
            fd.setMulti(true);
        }
        fd.save();
        if (!children.getJSONObject("children").isEmpty())
            recursiveNode(flowDesignNo, children.getString("id"), children.getJSONObject("children"));
    }
    
    /**
     * @note 获取待我审批的流程
     * @time 2024年03月26日 12:46:47
     * @author Ray
     */
    @RequestMapping("getFlow")
    @WebLog(description = "获取待我审批的流程")
    public Ret getFlow() {
        String sql = "SELECT t1.* FROM flow t1 right JOIN " +
                "(select distinct region,flow_no from (SELECT region,flow_no FROM flow_node WHERE region = '" + getSessionUserRegion() + "' and multi = 0 and is_delete = 0 and userid = '" + getSessionUserId() + "' and statu = 1 " +
                "union all SELECT region,flow_no FROM flow_node_multi WHERE region = '" + getSessionUserRegion() + "' and is_delete = 0 and userid = '" + getSessionUserId() + "' and statu = 1) t) t2" +
                " ON t1.no = t2.flow_no and t1.region = t2.region";
        List<Record> list = Db.use(base).find(sql);
        return Ret.ok("msg", "成功");
    }
    
    /**
     * @note 处理审批流程
     * @time 2024年03月26日 12:47:23
     * @author Ray
     */
    @RequestMapping("handle")
    @WebLog(description = "处理审批流程")
    @Transactional("baseTransactionManager")
    public Ret handle(@RequestBody JSONObject param) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            Flow flow = Flow.dao.findFirst("select * from flow where no = ?", param.getString("flow_no"));
            FlowNode thisNode = FlowNode.dao.findById(param.getIntValue("id"));
            //单人审批模式
            if (!thisNode.getMulti()) {
                thisNode.setComments(param.getString("comments"))
                        .setStatu(param.getIntValue("statu"))
                        .setHandleTime(new Date()).update();
                if (param.getIntValue("statu") == 2) {
                    flowService.nextNode(flow, thisNode);
                } else if (param.getIntValue("statu") == 3) {
                    flowService.frontNode(flow, thisNode);
                }
            }
            //多人审批模式
            else {
                FlowNodeMulti fnm = FlowNodeMulti.dao.findById(param.getIntValue("flow_node_multi_id"));
                if (fnm.getStatu() != 1) {
                    return Ret.fail("流程处理失败：当前节点已被其他人处理，您无需再处理");
                }
                fnm.setStatu(param.getIntValue("statu"))
                        .setComments(param.getString("comments"))
                        .setHandleTime(new Date())
                        .update();
                if (param.getIntValue("statu") == 2) {
                    //会签
                    if (thisNode.getMode().equals("AND")) {
                        List<FlowNodeMulti> list = FlowNodeMulti.dao.find("select * from flow_node_multi where flow_no = ? and flow_node_no = ? and id != ? and statu = 1", thisNode.getFlowNo(), thisNode.getNo(), fnm.getId());
                        if (list.isEmpty()) {
                            thisNode.setHandleTime(new Date());
                            thisNode.setStatu(2).update();
                            flowService.nextNode(flow, thisNode);
                        }
                    }
                    //或签
                    else {
                        thisNode.setStatu(param.getIntValue("statu"))
                                .setHandleTime(new Date()).update();
                        flowService.nextNode(flow, thisNode);
                    }
                } else if (param.getIntValue("statu") == 3) {
                    thisNode.setStatu(3).update();
                    flowService.frontNode(flow, thisNode);
                }
                //修改其他人处理状态
                Db.use(base).update("update flow_node_multi set statu = 5 where flow_no = ? and flow_node_no = ? and id != ? and statu = 1", thisNode.getFlowNo(), thisNode.getNo(), fnm.getId());
            }
            return Ret.ok("msg", "处理成功");
    }
    
    /**
     * @note 根据审批编号获取审批节点
     * @time 2024年03月26日 12:52:47
     * @author Ray
     */
    @RequestMapping("getFlowNode")
    @WebLog(description = "根据审批编号获取审批节点")
    public Ret getFlowNode(String flow_no) {
        List<Record> list = Db.use(base).find("select * from flow_node where flow_no = ?", flow_no);
        for (Record r : list) {
            if (r.getBoolean("multi")) {
                List<FlowNodeMulti> fnm = FlowNodeMulti.dao.find("select * from flow_node_multi where flow_no = ? and flow_node_no = ?", flow_no, r.getStr("no"));
                r.set("multi_list", fnm);
            }
        }
        return Ret.ok("msg", "成功").setJson("list",list);
    }
}
